package com.pic.mgt.syushin;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import org.springframework.dao.DataAccessException;

import com.pic.mgt.IgxStatus;
import com.pic.mgt.controller.BusinessUnitController;
import com.pic.mgt.dao.AbstractBusinessMgtInfoBean;
import com.pic.mgt.dao.syushin.SyushinBusinessMgtDao;
import com.pic.mgt.dao.syushin.SyushinBusinessMgtInfoBean;
import com.pic.mgt.executer.UnitDispatcher;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.manager.terminal.TerminalManager;
import com.pic.mgt.syushin.unit.BatchSyushinBusinessUnit;
import com.pic.mgt.syushin.unit.RealSyushinBusinessUnit;
import com.pic.mgt.syushin.unit.RedoBatchSyushinBusinessUnit;
import com.pic.mgt.syushin.unit.RedoRealSyushinBusinessUnit;
import com.pic.mgt.syushin.unit.SyushinBusinessUnit;
import com.pic.mgt.unit.Business;
import com.pic.mgt.unit.Redoable;

public class SyushinBusinessUnitController extends BusinessUnitController {
	private UnitDispatcher syushinBusinessUnitDispatcher;
	private TerminalManager syushinTerminalManager;
	
	@Override
	protected Map<String, Object> getDbBusinessMgtInsertBasicValuesMap(Business business) {
		SyushinBusinessUnit syushinBusinessUnit = (SyushinBusinessUnit)business;
		
		Map<String ,Object> insertValuesMap = new HashMap<String, Object>();
		
		insertValuesMap.put(SyushinBusinessMgtDao._confirmationFile, syushinBusinessUnit.getConfirmationFilename());
		insertValuesMap.put(SyushinBusinessMgtDao._targetFile, syushinBusinessUnit.getTargetFilename());
		insertValuesMap.put(SyushinBusinessMgtDao._type, syushinBusinessUnit.getBusinessType());
		insertValuesMap.put(SyushinBusinessMgtDao._targetFilesize, syushinBusinessUnit.getTargetFile().length());
		insertValuesMap.put(SyushinBusinessMgtDao._status, IgxStatus.BUSINESS_LOADED);
		insertValuesMap.put(SyushinBusinessMgtDao._unitName, syushinBusinessUnit.getUnitName());
		insertValuesMap.put(SyushinBusinessMgtDao._terminalId, syushinBusinessUnit.getTerminalID());
		insertValuesMap.put(SyushinBusinessMgtDao._uploadingTime, new Timestamp(syushinBusinessUnit.getUploadTime().getTime()));
		
		return insertValuesMap;
	}
	
	@Override
	protected String checkIsEffectiveTerminal(Business business) {
		SyushinBusinessUnit syushinBusinessUnit = (SyushinBusinessUnit)business;
		// 判斷是否為有效的端末並回傳
		
		if (this.syushinTerminalManager.
				isEffectiveTerminalId(syushinBusinessUnit.getTerminalID())) {
			return null;
		}
		else {
			return syushinBusinessUnit.getTerminalID();
		}
	}

	@Override
	public void doBusinessAction(Business business) {
		if (IgxLog.messageLog.isDebugMode()) {
			IgxLog.messageLog.debug(this,
					"Transmiting syushin business '{}' to syushin dispatcher.",
					business.getUnitName());
		}
		
		// 將 Business 交給 UnitDispatcher 去做執行
		syushinBusinessUnitDispatcher.sendToUnitExecuter(business);
	}
	
	@Override
	public void destory() {
		super.destory();
		
		if (syushinBusinessUnitDispatcher != null) {
			syushinBusinessUnitDispatcher.destory();
		}
	}
	
	@Override
	protected Redoable wrapToAnRedoableBusiness(Business business) {
		Redoable redoableBusiness = null;
		
		if (BatchSyushinBusinessUnit.class.isInstance(business)) {
			redoableBusiness = new RedoBatchSyushinBusinessUnit((BatchSyushinBusinessUnit)business);
		}
		else if (RealSyushinBusinessUnit.class.isInstance(business)) {
			redoableBusiness = new RedoRealSyushinBusinessUnit((RealSyushinBusinessUnit)business);
		}
		
		return redoableBusiness;
	}
	
	@Override
	public AbstractBusinessMgtInfoBean getBusinessMgtInfoBeanInDB(
			String unitName) throws DataAccessException {
		SyushinBusinessMgtDao syushinBusinessMgtDao = (SyushinBusinessMgtDao)super.businessMgtDao;
		
		SyushinBusinessMgtInfoBean syushinBusinessMgtInfoBean =
			syushinBusinessMgtDao.findSyushinBusinessMgtInfoByUnitName(unitName);
		
		if (null == syushinBusinessMgtInfoBean) {
			return null;
		}
		else {
			return syushinBusinessMgtInfoBean;
		}
	}
	
	// --- getter and setter ---

	public void setSyushinBusinessUnitDispatcher(UnitDispatcher syushinBusinessUnitDispatcher) {
		this.syushinBusinessUnitDispatcher = syushinBusinessUnitDispatcher;
	}

	public void setSyushinTerminalManager(TerminalManager syushinTerminalManager) {
		this.syushinTerminalManager = syushinTerminalManager;
	}
}
